package com.kashow.injector.module;

import android.content.Context;
import android.os.Build;
import android.webkit.WebSettings;

import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.kashow.AppContext;
import com.kashow.BuildConfig;
import com.kashow.C;
import com.kashow.api.ApiService;
import com.kashow.base.AppManager;
import com.kashow.base.cookie.PersistentCookieStore;
import com.kashow.base.rx.RxManager;
import com.kashow.base.utils.HttpsUtil;
import com.kashow.injector.ContextLife;
import com.orhanobut.logger.Logger;
import com.securepreferences.SecurePreferences;

import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import okhttp3.Cache;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

@Module
public class ApplicationModule {

    private AppContext mApplication;

    private Socket mSocket;

    public ApplicationModule(AppContext application) {
        mApplication = application;
        Logger.init(C.LOG_TAG);
    }

    @Provides
    @Singleton
    @ContextLife("Application")
    public Context provideContext() {
        return mApplication.getApplicationContext();
    }

    @Provides
    @Singleton
    public AppContext provideAppContext() {
        return mApplication;
    }

    @Provides
    @Singleton
    public OkHttpClient provideOkHttpClient() {
        HttpLoggingInterceptor mLoggingInterceptor;
        mLoggingInterceptor = new HttpLoggingInterceptor();
        mLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        PersistentCookieStore mCookieStore = new PersistentCookieStore(mApplication.getApplicationContext());
        HttpsUtil.SSLParams sslParams = HttpsUtil.getSslSocketFactory(null,null,new Buffer().writeUtf8(C.CER_TEST).inputStream());
        OkHttpClient.Builder builder =  new OkHttpClient.Builder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                        if (cookies != null && cookies.size() > 0) {
                            for (Cookie item : cookies) {
                                if (mCookieStore != null) {
                                    mCookieStore.add(url, item);
                                }
                            }
                        }
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl url) {
                        List<Cookie> cookies = mCookieStore.get(url);
                        return cookies;
                    }
                })
                .addInterceptor(new CacheCookieInterceptor())
                .connectTimeout(8, TimeUnit.SECONDS)
                .writeTimeout(20,TimeUnit.SECONDS)
                .readTimeout(20,TimeUnit.SECONDS)
                .cache(new Cache(new File(mApplication.getCacheDir(),"ok_http_cache"),1024 * 1024 * 80))
                .sslSocketFactory(sslParams.sSLSocketFactory,sslParams.trustManager);

        if (BuildConfig.BuildType != 3) {
//            if (BuildConfig.BuildType == 1) {
//                return builder.addInterceptor(mLoggingInterceptor)
//                        .addInterceptor(new ChuckInterceptor(mApplication.getApplicationContext()))
//                        .addNetworkInterceptor(new StethoInterceptor()) //这里有个坑
//                        .build();
//            }
            return builder.addInterceptor(mLoggingInterceptor)
                    //.addInterceptor(new ChuckInterceptor(mApplication.getApplicationContext()))
                   .addNetworkInterceptor(new StethoInterceptor()) //这里有个坑
                   .build();
        } else {
            return builder.build();
        }
    }


    @Provides
    @Singleton
    public Retrofit provideRetrofit(OkHttpClient okHttpClient) {
        String baseUrl = BuildConfig.BuildType == 1 ? C.BASE_URL_DEUBG : C.BASE_URL;
        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(okHttpClient)
                .build();
    }

    @Provides
    @Singleton
    public ApiService provideApiService(Retrofit retrofit) {
        return retrofit.create(ApiService.class);
    }

    @Provides
    @Singleton
    public AppManager provideAppManager() {
        return new AppManager();
    }


    @Provides
    @Singleton
    public RxManager provideRxManager() {
        return new RxManager();
    }


    @Provides
    @Singleton
    public SecurePreferences provideSecurePreferences() {
        return new SecurePreferences(mApplication.getApplicationContext(),"kashowvr","kashowvr");
    }

    class CacheCookieInterceptor implements Interceptor {

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            //request = request.newBuilder().removeHeader("User-Agent").addHeader("User-Agent", Device.getUserAgent()).build();

//            if (!AppContext.Utils.g().isAvailable()) {
//                request = request.newBuilder()
//                        .addHeader("Cookie", mCookieStore.getCookies().toString())
//                        .cacheControl(CacheControl.FORCE_CACHE)
//                        .build();
//            } else {
//                request = request.newBuilder()
//                        .addHeader("Cookie", mCookieStore.getCookies().toString())
//                        .build();
//            }

            Response originalResponse = chain.proceed(request);
            if (AppContext.Utils.g().isAvailable()){
                String cacheControl = "Cache-Control: public, max-age=3600";
                if (AppContext.Utils.g().isWifi()) {
                    cacheControl = "Cache-Control: no-cache";
                }
                return originalResponse.newBuilder()
                        .header("Cache-Control", cacheControl)
                        .removeHeader("Pragma")
                        .build();
            } else {
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, only-if-cached, max-stale=2419200")
                        .removeHeader("Pragma")
                        .build();
            }
        }
    }

    public static String getUserAgent() {
        String userAgent = "";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            try {
                userAgent = WebSettings.getDefaultUserAgent(AppContext.context());
            } catch (Exception e) {
                userAgent = System.getProperty("http.agent");
            }
        } else {
            userAgent = System.getProperty("http.agent");
        }
        StringBuffer sb = new StringBuffer();
        for (int i = 0, length = userAgent.length(); i < length; i++) {
            char c = userAgent.charAt(i);
            if (c <= '\u001f' || c >= '\u007f') {
                sb.append(String.format("\\u%04x", (int) c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

}
